package com.gitee.dupe.oauth.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.gitee.dolt.cache.repository.CacheOps;
import com.gitee.dolt.core.base.Result;
import com.gitee.dolt.core.cache.model.CacheKey;
import com.gitee.dolt.core.cache.model.CacheKeyBuilder;
import com.gitee.dolt.core.context.ContextConstants;
import com.gitee.dolt.security.model.AuthInfo;
import com.gitee.dolt.security.model.SysToken;
import com.gitee.dolt.security.model.SysUser;
import com.gitee.dolt.security.properties.SecurityProperties;
import com.gitee.dupe.common.captcha.CaptchaService;
import com.gitee.dupe.oauth.dto.GetResetPasswordCodeDTO;
import com.gitee.dupe.oauth.dto.LoginDTO;
import com.gitee.dupe.oauth.dto.ResetPasswordByCodeDTO;
import com.gitee.dupe.oauth.enumeration.GrantType;
import com.gitee.dupe.oauth.granter.TokenGranterBuilder;
import com.gitee.dupe.oauth.service.OauthService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.time.Duration;
import java.util.Date;

/**
 * @author LYH
 */
@Slf4j
@RestController
@RequestMapping("/oauth")
@RequiredArgsConstructor
@Api(value = "用户授权认证", tags = "用户授权认证")
public class OauthController {

    private final CaptchaService captchaService;
    private final TokenGranterBuilder tokenGranterBuilder;
    private final OauthService oauthService;
    private final CacheOps cacheOps;
    private final SecurityProperties securityProperties;

//    @ApiOperation(value = "加密登录接口", notes = "加密登录时调用")
//    @PostMapping(value = "/login")
//    @Decrypt(decryptedClass = LoginDTO.class)
//    public Result<AuthInfo> login(@Validated @RequestBody EncryptedReq<LoginDTO> encryptedReq) {
//        LoginDTO loginDTO = encryptedReq.getData();
//        return Result.ok(tokenGranterBuilder.getGranter(loginDTO.getGrantType()).grant(loginDTO));
//    }

    @ApiOperation(value = "登录/刷新token", notes = "登录时调用")
    @PostMapping(value = "/login")
    public Result login(@Validated @RequestBody LoginDTO loginDTO) {
        SysToken token = tokenGranterBuilder.getGranter(loginDTO.getGrantType()).grant(loginDTO).getToken();
        if (securityProperties.getJwt().getShortToken()) {
//            if (GrantType.REFRESH_TOKEN.equals(loginDTO.getGrantType())) {
//                cacheOps.del(StrUtil.concat(true, ContextConstants.SHORT_TOKEN_PREFIX, ":", loginDTO.getToken()));
//            }
            Duration dur = Duration.ofSeconds(token.getExpire());
            String uuid = IdUtil.simpleUUID();
            CacheKey cacheKey = new CacheKey(StrUtil.concat(true,
                    ContextConstants.SHORT_TOKEN_PREFIX, ":", uuid), dur);
            cacheOps.set(cacheKey, token.getToken());
            token.setToken(uuid);
        }
        return Result.ok(token);
    }

    @ApiOperation(value = "获取用户信息", notes = "登录后调用")
    @PostMapping(value = "/userInfo")
    public Result userInfo(@RequestParam String token) {
        SysUser userInfo = oauthService.getUserInfo(token);
        return Result.ok(userInfo);
    }

    @ApiOperation(value = "图形验证码", notes = "验证码")
    @GetMapping(value = "/captcha", produces = "image/png")
    public void captcha(@RequestParam(value = "key") String key, HttpServletResponse response) {
        captchaService.renderCaptcha(key, response);
    }

    @PostMapping("/getResetPasswordCode")
    @ApiOperation(value = "获取重置密码验证码")
    public Result getResetPasswordCode(@RequestBody @Valid GetResetPasswordCodeDTO getResetPasswordCodeDto) {
        oauthService.getResetPasswordCode(getResetPasswordCodeDto);
        return Result.ok();
    }

    @PostMapping("/resetPasswordByCode")
    @ApiOperation(value = "通过验证码重置密码")
    public Result resetPasswordByCode(@RequestBody @Valid ResetPasswordByCodeDTO resetPasswordByCodeDTO) {
        oauthService.resetPasswordByCode(resetPasswordByCodeDTO);
        return Result.ok();
    }

}
